package com.chenl.provider.util;

import cn.hutool.core.util.ClassUtil;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.*;

//或可采用hutool的ClassUtil
public class ScanUtil {
    //--------------------------------------------扫描类----------------------------------------------------
    /**
     * ClassPathScanningCandidateComponentProvider 可以通过指定包名或者类路径来进行扫描，并支持添加多个过滤器来筛选所需的组件。
     * 常见的过滤器类型有基于注解的过滤器（例如 AnnotationTypeFilter）和基于类型的过滤器（例如 AssignableTypeFilter）等
     * @param packageName
     * @return
     */
    public static Set<Class<?>> scanClazz(String packageName,Class annoClass) {
        Set<Class<?>> feignInterfaces = new HashSet<>();
        // 创建类路径扫描提供者
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        //添加过滤器，如AnnotationTypeFilter就是过滤带有@Component注解的类
        scanner.addIncludeFilter(new AnnotationTypeFilter(annoClass));
        // 扫描指定包下的所有类
        for (org.springframework.beans.factory.config.BeanDefinition beanDef : scanner.findCandidateComponents(packageName)) {
            try {
                // 获取类的实例
                Class<?> clazz = Class.forName(beanDef.getBeanClassName());
                feignInterfaces.add(clazz);
            } catch (ClassNotFoundException e) {
                // 处理异常
            }
        }
        return feignInterfaces;
    }

    public static Object invokeMethod(Object clazz, String methodName) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
        Object result =null;
        try {
            // 获取方法对象
            Method method = clazz.getClass().getMethod(methodName);
            // 调用方法
            result = method.invoke(clazz);
            return result;
        } catch (Exception e) {
            // 处理异常
            e.printStackTrace();
            throw e;
        }
    }
    //--------------------------------------------扫描接口----------------------------------------------------
    public static List<Class<?>> scanInterfaces(String packageName) throws ClassNotFoundException, IOException {
        List<Class<?>> interfaces = new ArrayList<>();
        // 将包名转换为路径
        String path = packageName.replace('.', '/');
        // 获取当前线程的类加载器
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        // 使用类加载器加载指定包下的所有资源
        Enumeration<URL> resources = classLoader.getResources(path);
        while (resources.hasMoreElements()) {
            URL resource = resources.nextElement();
            File file = new File(resource.getFile());
            if (file.isDirectory()) {
                // 如果资源是目录，则递归扫描子目录
                scanInterfacesInDirectory(packageName, file, interfaces);
            } else {
                // 如果资源是文件，则直接加载类
                String className = packageName + '.' + file.getName().substring(0, file.getName().length() - 6);
                Class<?> clazz = Class.forName(className);
                // 检查是否是接口
                if (clazz.isInterface()) {
                    interfaces.add(clazz);
                }
            }
        }
        return interfaces;
    }

    private static void scanInterfacesInDirectory(String packageName, File directory, List<Class<?>> interfaces) throws ClassNotFoundException {
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    scanInterfacesInDirectory(packageName + '.' + file.getName(), file, interfaces);
                } else {
                    String className = packageName + '.' + file.getName().substring(0, file.getName().length() - 6);
                    Class<?> clazz = Class.forName(className);
                    // 检查是否是接口
                    if (clazz.isInterface()) {
                        interfaces.add(clazz);
                    }
                }
            }
        }
    }
    public static Set<Class<?>> scanInterfaces(String packageName,Class claz) {
        Set<Class<?>> interfaces = new HashSet<>();

        // 创建类路径扫描提供者
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        scanner.addIncludeFilter(new AnnotationTypeFilter(claz));

        // 扫描指定包下的所有类
        for (org.springframework.beans.factory.config.BeanDefinition beanDef : scanner.findCandidateComponents(packageName)) {
            try {
                // 获取类的实例
                Class<?> clazz = Class.forName(beanDef.getBeanClassName());
                // 检查实例是否是接口
                if (clazz.isInterface()) {
                    interfaces.add(clazz);
                }
            } catch (ClassNotFoundException e) {
                // 处理异常
            }
        }
        return interfaces;
    }



}
